/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - resource
// Copyright( c) 2014.  All Rights Reserved
//
// File:		AETextureManager.h
// Author:		Gianluca Belardelli
// Date:		02/10/2014
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AETEXTUREMANAGER_H_
#define _AETEXTUREMANAGER_H_

#define AE_MAX_TEXTURE_LOADER		4

class AEResourceSnapshotEntry;

/// \brief
///   Texture resource manager base class that implements the IVTextureLoader interface
class AETextureManager : public AEResourceManager
{
// Members
protected:
	AEINT32						m_nProviderCount;
	AETextureLoaderI			*m_lpLoader[AE_MAX_TEXTURE_LOADER];

public:
	static AETextureManager *g_lpGlobalManager; ///< set by the engine

// Methods
public:
	AE_DECLARE_PLACEMENT_ALLOCATOR();

	/// \brief Costruttore
	AE_DLLIMPEXP AETextureManager( const char *lpName = AE_RESOURCEMANAGER_TEXTURES );

	///
	/// @name Resource manager overrides
	/// @{
	///

	/// \brief
	///   Overridden function to create a texture resource from the specified file
	AE_DLLIMPEXP virtual AEResource *CreateResource( const char *lpFilename, AEINT32 nFlags = 0 );

	///
	/// @}
	///

	///
	/// @name Render Target Related
	/// @{
	///


	/// \brief
	///   Creates a renderable 2D texture that can be used as a render target
	/// 
	/// Since a renderable texture object is derived from VTextureObject, it can also be used as a
	/// standard texture.
	/// 
	/// The texture properties are passed through the VisRenderableTextureConfig_t structure.
	/// 
	/// By default the returned texture has the VRESOURCEFLAG_AUTODELETE flag set so it gets deleted
	/// as soon as there is no reference to it anymore.
	/// 
	/// \param szName
	///   Internal key of the renderable texture. Shows up in the resource viewer and is also used to
	///   find a texture.
	/// 
	/// \param config
	///   Config structure that defines the renderable texture properties
	///
	/// \param iLoadingFlags
	///   Optional loading flags
	/// 
	/// \return
	///   VisRenderableTexture_cl* pRTObject: Pointer to renderable texture object, derived from
	///   VTextureObject. NULL if creation failed.
	/// 
	/// \sa VisRenderableTextureConfig_t
	/// \sa VisTextureManager_cl::FindRenderableTexture
	/// \sa VisRenderContext_cl
	/// \sa VisRenderableTexture_cl
	AE_DLLIMPEXP AETexture* CreateRenderableTexture( const char *lpName, AERenderableTextureConfig &rtConfig, AEUINT32 uiLoadingFlags = 0 );

	/// \brief
	///   Creates a renderable cube map that can be used as a render target
	/// 
	/// Since a renderable cube map object is derived from VTextureObject, it can also be used as a
	/// regular texture.
	/// 
	/// The texture properties are passed through the VisRenderableTextureConfig_t structure.
	/// 
	/// By default the returned texture has the VRESOURCEFLAG_AUTODELETE flag set so it gets deleted
	/// as soon as there is no reference to it anymore.
	/// 
	/// \param szName
	///   Internal key of the renderable cube map. Shows up in the resource viewer and may also be
	///   used to find a texture again.
	/// 
	/// \param config
	///   Config structure that defines the renderable texture's properties
	/// 
	/// \param iLoadingFlags
	///   Optional loading flags
	/// 
	/// \return
	///   VisRenderableCubeMap_cl* pRTObject: Pointer to renderable cube map object, derived from
	///   VTextureObject. NULL if creation failed.
	/// 
	/// \sa VisRenderableTextureConfig_t
	/// \sa VisTextureManager_cl::FindRenderableTexture
	/// \sa VisRenderContext_cl
	//AE_DLLIMPEXP VisRenderableCubeMap_cl* CreateRenderableCubeMap(const char *szName, VisRenderableTextureConfig_t &config,
	//																unsigned int iLoadingFlags = VTM_DEFAULT_FLAGS);

	///
	/// @name IVTextureLoader overrides
	/// @{
	///

	/// \brief
	///   Overridden function to load a 2D texture from file
	AE_DLLIMPEXP virtual AETexture* Load2DTextureFromFile( const char *lpFilename, AEINT32 nFlags = 0 );

	/// \brief
	///   Overridden function to load a 3D volume texture from file
	AE_DLLIMPEXP virtual AETexture* Load3DTextureFromFile( const char *lpFilename, AEINT32 nFlags = 0 );
  
	#if defined(AE_SUPPORTS_2D_TEXTURE_ARRAYS)
		/// \brief
		///   Overridden function to load a 2D texture array from file
		AE_DLLIMPEXP virtual AETexture *Load2DArrayTextureFromFile( const char *lpFilename, AEINT32 nFlags = 0 );
	#endif

	/// \brief
	///   Overridden function to load a cubemap texture from file
	AE_DLLIMPEXP virtual AETexture *LoadCubemapTextureFromFile( const char *lpFilename, AEINT32 nFlags = 0 );  

	/// \brief
	///   Overridden function to create a cubemap render target proxy with the specified key
	AE_DLLIMPEXP virtual AETexture *GetRenderableCubemap( const char *lpKey, AEBOOL32 bForceCreate = 1 );

	///
	/// @}
	///

	///
	/// @name Custom Texture Format Providers
	/// @{
	///

	/// \brief
	///   Registers a custom texture format provider. See IVTextureFormatProvider. IVisPlugin_cl::OnInitEnginePlugin is a good place to call this function.
	AE_FORCEINLINE void RegisterLoaderProvider( AETextureLoaderI *lpProvider );

	/// \brief
	///   De-registers a custom texture format provider that has been registered with RegisterFormatProvider. See IVTextureFormatProvider. IVisPlugin_cl::OnDeInitEnginePlugin is a good place to call this function.
	AE_FORCEINLINE void DeRegisterLoaderProvider( AETextureLoaderI *lpProvider );

	/// \brief
	///   Returns the number of installed custom texture format providers (0 by default)
	AE_FORCEINLINE AEINT32 GetLoaderProviderCount( void ) const;

	/// \brief
	///   Returns the provider instance with specified index. iIndex must be in valid range [0..GetFormatProviderCount()-1]
	AE_FORCEINLINE AETextureLoaderI &GetLoaderProvider( AEINT32 nIndex ) const;

	/// \brief
	///   Helper function to return the first matching installed provider (or NULL) for the passed file extension (extension string without '.'). 
	AE_DLLIMPEXP AETextureLoaderI *GetLoaderForExtension( const char *lpExt );

	///
	/// @}
	///

	///
	/// @name Callbacks and Logging
	/// @{
	///

	/// \brief
	///   Implementations can respond to texture not found warnings
	AE_DLLIMPEXP virtual void TriggerFileNotFound( const char *lpFilename );

	/// \brief
	///   Implementations can respond to texture loading errors
	AE_DLLIMPEXP virtual void TriggerLoadingError( const char *lpFilename, const char *lpErrorMsg );

	/// \brief
	///   Implementations can provide a log for error/warning/info output
	//AE_DLLIMPEXP virtual IVLog* GetLoadingLog( AETexture *lpLoadingRes ) {return NULL;}

	/// \brief
	///   Implementations must trigger the texture loading callback after loading a texture
	//AE_DLLIMPEXP virtual void TriggerLoadingCallback( AETextureLoadingDataObject *lpData ) {}

	///
	/// @}
	///

	///
	/// @name Cleanup
	/// @{
	///

	/// \brief
	///   Implementations must unbind the passed texture so the texture can be destroyed
	AE_DLLIMPEXP virtual void UnbindTexture( AETexture *lpTexture );

	///
	/// @}
	///

	/// @}
	/// @name Device information
	/// @{

	/// \brief
	///   Returns the maximum texture size available on the current device / platform
	AE_DLLIMPEXP AEINT32 GetMaxTextureSize( void ) const;

	/// \brief
	///   Sets the maximum texture size available on the current device / platform (used internally during initialization for platforms
	///   where this value can vary)
	AE_DLLIMPEXP void SetMaxTextureSize( AEINT32 nMaxTextureSize );

	/// @}


	///
	/// @name Global access
	/// @{
	///

	/// \brief
	///   Sets a global manager so the base library can access it
	AE_DLLIMPEXP static void SetGlobalManager( AETextureManager *lpManager );

	/// \brief
	///   Returns a reference to the global instance
	AE_DLLIMPEXP static AETextureManager &GetGlobalManager( void );

	

	///
	/// @}
	///
};

#include "AETextureManager.inl"

#endif // _AETEXTUREMANAGER_H_

